package org.qydjk.common.util;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisTemplateUtil {
    public static int defExSecond = 365 * 24 * 60 * 60;
    private static RedisTemplate redisTemplate;

    public static void set(String key, Object value) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, value);
    }

    public static Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    public static void setList(String key, List<?> value) {
        ListOperations listOperations = redisTemplate.opsForList();
        listOperations.leftPush(key, value);
    }

    public static Object getList(String key) {
        return redisTemplate.opsForList().leftPop(key);
    }

    public static void setSet(String key, Set<?> value) {
        SetOperations setOperations = redisTemplate.opsForSet();
        setOperations.add(key, value);
    }

    public static Object getSet(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    public static void setHash(String key, Map<String, ?> value) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.putAll(key, value);
    }

    public static Object getHash(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    public static void delete(String key) {
        redisTemplate.delete(key);
    }



    /**
     * 存储 使用序列化
     * @param key
     * @param value
     */
    public static void setWithByte(final byte[] key, final byte[] value) {
        redisTemplate.execute(new RedisCallback() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.set(key, value);
                connection.expire(key, defExSecond);
                return 1L;
            }
        });
    }

    /**
     * 存储 使用序列化
     * @param key
     * @param value
     */
    public static void setWithByte(String key, Object value) {
        setWithByte(SerializeUtil.serialize(key), SerializeUtil.serialize(value));
    }

    /**
     * 批量存储 使用序列化
     * @param map
     */
    public static void setWithByte(Map<String,Object> map) {
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                Iterator<String> it = map.keySet().iterator();
                while (it.hasNext()){
                    String k = it.next();
                    Object v = map.get(k);
                    redisConnection.set(SerializeUtil.serialize(k), SerializeUtil.serialize(v));
                }
                return 1L;
            }
        });
    }

    /**
     * 批量存储 使用序列化
     * @param list
     */
    public static void setWithByte(List<Map<String,Object>> list) {
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                for (Map<String,Object> map : list){
                    String k = map.get("k").toString();
                    Object v = map.get("v");
                    redisConnection.set(SerializeUtil.serialize(k), SerializeUtil.serialize(v));
                }
                return 1L;
            }
        });
    }

    /**
     * 读取 使用序列化
     * @param key
     * @return
     */
    public static Object getWithByte(final String key) {
        return redisTemplate.execute(new RedisCallback() {
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                return SerializeUtil.deserialize(connection.get(SerializeUtil.serialize(key)));
            }
        });
    }

    /**
     * 根据key进行删除
     * @param keys
     */
    public static void delWithByte(final String... keys) {
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                for (int i = 0; i < keys.length; i++) {
                    connection.del(keys[i].getBytes());
                }
                return null;
            }
        });
    }

    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void setDefExSecond(int defExSecond) {
        this.defExSecond = defExSecond;
    }

    public int getDefExSecond() {
        return defExSecond;
    }
}
